﻿using System;
using System.Threading;
using Teigha.Core;
using Teigha.TD;

namespace OdaOperation.Extends
{
    public static class PurgeExtend
    {
        public static void PurgeAll(this OdDbDatabase database)
        {
            try
            {
                MemoryTransaction value = MemoryManager.GetMemoryManager().StartTransaction(Thread.CurrentThread.ManagedThreadId);
                OdDbObjectIdArray odDbObjectIdArray = new OdDbObjectIdArray();
                addBlocks(database.getBlockTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addDictionaryRecords(database.getDetailViewStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addTableRecords(database.getDimStyleTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addDictionaryRecords(database.getGroupDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addTableRecords(database.getLayerTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addTableRecords(database.getLinetypeTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addDictionaryRecords(database.getMaterialDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addDictionaryRecords(database.getMLeaderStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addDictionaryRecords(database.getPlotStyleNameDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addTableRecords(database.getTextStyleTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addDictionaryRecords(database.getMLStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addDictionaryRecords(database.getSectionViewStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addDictionaryRecords(database.getTableStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addDictionaryRecords(database.getVisualStyleDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                addTableRecords(database.getRegAppTableId().openObject() as OdDbSymbolTable, odDbObjectIdArray);
                addDictionaryRecords(database.getNamedObjectsDictionaryId().openObject() as OdDbDictionary, odDbObjectIdArray);
                OdDbDictionary odDbDictionary = database.getNamedObjectsDictionaryId().safeOpenObject() as OdDbDictionary;
                OdDbDictionary dbDictionary = odDbDictionary.getAt("ACAD_SCALELIST", OpenMode.kForWrite) as OdDbDictionary;
                addDictionaryRecords(dbDictionary, odDbObjectIdArray);
                OdDbObjectIdGraph odDbObjectIdGraph = new OdDbObjectIdGraph();
                foreach (OdDbObjectId item in odDbObjectIdArray)
                {
                    OdDbObjectIdGraphNode odDbObjectIdGraphNode = OdDbObjectIdGraphNode.createObject();
                    odDbObjectIdGraphNode.setId(item);
                    odDbObjectIdGraph.addNode(odDbObjectIdGraphNode);
                }

                OdDbObjectId odDbObjectId = new OdDbObjectId();
                odDbObjectId = odDbDictionary.getAt("ACAD_DGNLINESTYLECOMP");
                if (!odDbObjectId.isErased())
                {
                    OdDbDictionary dbDictionary2 = odDbObjectId.safeOpenObject() as OdDbDictionary;
                    addDictionaryRecords(dbDictionary2, odDbObjectIdArray);
                    odDbObjectIdArray.Add(odDbObjectId);
                }

                database.purge(odDbObjectIdGraph);
                OdDbObjectIdGraphNode odDbObjectIdGraphNode2 = odDbObjectIdGraph.findNode(odDbObjectId);
                if (odDbObjectIdGraphNode2 != null)
                {
                    odDbObjectIdGraph.delNode(odDbObjectIdGraphNode2);
                }

                odDbObjectIdArray.Clear();
                for (int i = 0; i < odDbObjectIdGraph.numNodes(); i++)
                {
                    odDbObjectIdArray.Add(((OdDbObjectIdGraphNode)odDbObjectIdGraph.node(i)).id());
                }

                foreach (OdDbObjectId item2 in odDbObjectIdArray)
                {
                    item2.openObject(OpenMode.kForWrite)?.erase();
                }

                MemoryManager.GetMemoryManager().StopTransaction(value);
            }
            catch (Exception)
            {
            }
        }

        private static void addTableRecords(OdDbSymbolTable odDbSymbolTable, OdDbObjectIdArray ids)
        {
            OdDbSymbolTableIterator odDbSymbolTableIterator = odDbSymbolTable.newIterator();
            while (!odDbSymbolTableIterator.done())
            {
                ids.Add(odDbSymbolTableIterator.getRecordId());
                odDbSymbolTableIterator.step();
            }
        }

        private static void addDictionaryRecords(OdDbDictionary dbDictionary, OdDbObjectIdArray ids)
        {
            OdDbDictionaryIterator odDbDictionaryIterator = dbDictionary.newIterator();
            while (!odDbDictionaryIterator.done())
            {
                ids.Add(odDbDictionaryIterator.objectId());
                odDbDictionaryIterator.next();
            }
        }

        private static void addBlocks(OdDbSymbolTable pTable, OdDbObjectIdArray ids)
        {
            OdDbSymbolTableIterator odDbSymbolTableIterator = pTable.newIterator();
            while (!odDbSymbolTableIterator.done())
            {
                OdDbBlockTableRecord odDbBlockTableRecord = odDbSymbolTableIterator.getRecord() as OdDbBlockTableRecord;
                if (odDbBlockTableRecord != null && !odDbBlockTableRecord.isLayout())
                {
                    ids.Add(odDbBlockTableRecord.objectId());
                }

                odDbSymbolTableIterator.step();
            }
        }
    }
}